package com.example.common;

import com.example.exception.BaseException;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * 统一错误响应格式
 */
@Data
public class ErrorResponse {
    
    /**
     * 错误码
     */
    private String errorCode;
    
    /**
     * 错误消息
     */
    private String errorMessage;
    
    /**
     * 错误详情
     */
    private Object errorDetails;
    
    /**
     * 错误级别
     */
    private String errorLevel;
    
    /**
     * 错误分类
     */
    private String errorCategory;
    
    /**
     * 请求路径
     */
    private String path;
    
    /**
     * 请求方法
     */
    private String method;
    
    /**
     * 时间戳
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime timestamp;
    
    /**
     * 请求ID（用于追踪）
     */
    private String requestId;
    
    /**
     * 堆栈信息（仅开发环境）
     */
    private String stackTrace;
    
    /**
     * 用户友好的错误提示
     */
    private String userMessage;
    
    /**
     * 建议的解决方案
     */
    private String suggestion;
    
    /**
     * 额外的上下文信息
     */
    private Map<String, Object> context;
    
    public ErrorResponse() {
        this.timestamp = LocalDateTime.now();
    }
    
    public ErrorResponse(String errorCode, String errorMessage) {
        this();
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
    }
    
    public ErrorResponse(BaseException exception) {
        this();
        this.errorCode = exception.getErrorCode();
        this.errorMessage = exception.getErrorMessage();
        this.errorDetails = exception.getErrorDetails();
        this.errorLevel = exception.getErrorLevel() != null ? exception.getErrorLevel().name() : null;
        this.errorCategory = exception.getErrorCategory() != null ? exception.getErrorCategory().name() : null;
    }
    
    /**
     * 创建业务异常响应
     */
    public static ErrorResponse business(String errorCode, String errorMessage) {
        ErrorResponse response = new ErrorResponse(errorCode, errorMessage);
        response.setErrorCategory("BUSINESS");
        response.setErrorLevel("ERROR");
        return response;
    }
    
    /**
     * 创建系统异常响应
     */
    public static ErrorResponse system(String errorCode, String errorMessage) {
        ErrorResponse response = new ErrorResponse(errorCode, errorMessage);
        response.setErrorCategory("SYSTEM");
        response.setErrorLevel("ERROR");
        return response;
    }
    
    /**
     * 创建认证异常响应
     */
    public static ErrorResponse authentication(String errorCode, String errorMessage) {
        ErrorResponse response = new ErrorResponse(errorCode, errorMessage);
        response.setErrorCategory("AUTHENTICATION");
        response.setErrorLevel("ERROR");
        return response;
    }
    
    /**
     * 创建授权异常响应
     */
    public static ErrorResponse authorization(String errorCode, String errorMessage) {
        ErrorResponse response = new ErrorResponse(errorCode, errorMessage);
        response.setErrorCategory("AUTHORIZATION");
        response.setErrorLevel("ERROR");
        return response;
    }
    
    /**
     * 创建参数验证异常响应
     */
    public static ErrorResponse validation(String errorCode, String errorMessage) {
        ErrorResponse response = new ErrorResponse(errorCode, errorMessage);
        response.setErrorCategory("VALIDATION");
        response.setErrorLevel("ERROR");
        return response;
    }
    
    /**
     * 设置用户友好的错误提示
     */
    public ErrorResponse withUserMessage(String userMessage) {
        this.userMessage = userMessage;
        return this;
    }
    
    /**
     * 设置建议的解决方案
     */
    public ErrorResponse withSuggestion(String suggestion) {
        this.suggestion = suggestion;
        return this;
    }
    
    /**
     * 设置错误详情
     */
    public ErrorResponse withDetails(Object details) {
        this.errorDetails = details;
        return this;
    }
    
    /**
     * 设置上下文信息
     */
    public ErrorResponse withContext(Map<String, Object> context) {
        this.context = context;
        return this;
    }
    
    /**
     * 添加上下文信息
     */
    public ErrorResponse addContext(String key, Object value) {
        if (this.context == null) {
            this.context = new java.util.HashMap<>();
        }
        this.context.put(key, value);
        return this;
    }
    
    /**
     * 设置请求信息
     */
    public ErrorResponse withRequest(String path, String method) {
        this.path = path;
        this.method = method;
        return this;
    }
    
    /**
     * 设置请求ID
     */
    public ErrorResponse withRequestId(String requestId) {
        this.requestId = requestId;
        return this;
    }
    
    /**
     * 设置堆栈信息（仅开发环境）
     */
    public ErrorResponse withStackTrace(String stackTrace) {
        this.stackTrace = stackTrace;
        return this;
    }
    
    /**
     * 判断是否为用户错误（4xx）
     */
    public boolean isClientError() {
        return "BUSINESS".equals(errorCategory) || 
               "AUTHENTICATION".equals(errorCategory) || 
               "AUTHORIZATION".equals(errorCategory) || 
               "VALIDATION".equals(errorCategory);
    }
    
    /**
     * 判断是否为服务器错误（5xx）
     */
    public boolean isServerError() {
        return "SYSTEM".equals(errorCategory) || 
               "DATABASE".equals(errorCategory) || 
               "NETWORK".equals(errorCategory) || 
               "EXTERNAL".equals(errorCategory);
    }
    
    /**
     * 获取HTTP状态码
     */
    public int getHttpStatus() {
        if (isClientError()) {
            if ("AUTHENTICATION".equals(errorCategory)) {
                return 401; // Unauthorized
            } else if ("AUTHORIZATION".equals(errorCategory)) {
                return 403; // Forbidden
            } else if ("VALIDATION".equals(errorCategory)) {
                return 400; // Bad Request
            } else {
                return 400; // Bad Request
            }
        } else if (isServerError()) {
            return 500; // Internal Server Error
        } else {
            return 500; // Default to Internal Server Error
        }
    }
}
